<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="root">
        <p>{{name}}</p>
        <p>{{message}}</p>
    </div>
    <script>
        //1.获取模板
        var templateNode = document.querySelector('#root')
        //2.获取数据
        var data = {
            name:'一个新的名字',
            message:'一个新的消息'
        }
        let r = /\{\{(.+?)\}\}/g
        //3、将数据放到模板中
        //使用递归找到要放数据的地方
        function compiler(template,data){
            let ChildNodes = template.childNodes //取出子元素
            for(let i = 0; i < ChildNodes.length; i++){
                //在这里要判断子元素的类型，是元素节点还是文本节点  type = 1 为元素节点  type = 3为文本节点
                let type = ChildNodes[i].nodeType
                if(type === 1){
                    compiler(ChildNodes[i],data)
                }else if(type === 3){
                    //要获取文本节点内部的内容
                    let txt = ChildNodes[i].nodeValue
                    //使用正则匹配是否有{{}}
                    txt = txt.replace(r,function(a,b){  //这个replace函数会利用正则表达式去匹配txt文本中的内容，一旦匹配到，后面的回调函数就会被执行
                                                  //这个回调函数的第0个参数是通过正则匹配到的内容，第n个参数是正则中的第n组，因为正则表达式中使用一个圆括号，所以只有一组
                        let key = b.trim()  //这里是获取到卸载花括号里面的东西
                        let value = data[key]
                        return value
                    })
                    //让DOM中的文本与替换后的文本产生联系
                    ChildNodes[i].nodeValue = txt
                }
            }
        }
        //这里需要将DOM元素拷贝一份在操作，因为在操作过程中没有生成新的模板，是直接引用原来的模板，如果不拷贝一份，所有的
        //操作都会在原来的模板上进行，导致原来的模板就不存在了
        let generateNode = templateNode.cloneNode(true)
        console.log(templateNode)
        compiler(generateNode,data)
        console.log(generateNode)
        //4.挂载到页面
        //这里使用Dom方法替换root中的子元素
        root.parentNode.replaceChild(generateNode,root)

        /* 
        在整个操作中主要用到递归以及正则匹配的方法，先递归查找到模板中所有的文本节点，在通过正则匹配到这些文本节点中的{{}}差值
        表达式，通过replace方法获取到{{}}插值内部的的内容，将其替换成data中的内容即可
        */
       /* 
       另外上面代码也存在很大的问题：
       1.vue使用的是虚拟dom，二上面的代码是真实的dom
       2.只考虑了单属性（{{name}}），而vue中使用了大量的层级属性（{{person.name.firstname}}）
       3.vue中将所有的数据驱动代码都整合到vue的构造函数中了，上述代码没有整合。
       */
    </script>
</body>
</html>